﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;

namespace JasLib.Interop.Win32
{
    [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Unicode)]
    public delegate int BFFCALLBACK(HWND hwnd, BrowseForFolderMessageId uMsg, INT_PTR lParam, INT_PTR lpData);

    [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Unicode)]
    public delegate bool DESKTOPENUMPROC([In, MarshalAs(UnmanagedType.LPWStr)] string lpszDesktop, [In] UINT_PTR lParam);

    [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Unicode)]
    public delegate void ENABLECALLBACK(ref Guid SourceId, uint IsEnabled, TraceLevel Level, ulong MatchAnyKeyword, ulong MatchAllKeywords, ref EVENT_FILTER_DESCRIPTOR FilterData, UINT_PTR CallbackContext);

    [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Unicode)]
    public delegate void EVENT_CALLBACK(ref EVENT_TRACE pEvent);

    [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Unicode)]
    public delegate void EVENT_RECORD_CALLBACK([In] ref EVENT_RECORD EventRecord);

    [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Unicode)]
    public delegate uint EVENT_TRACE_BUFFER_CALLBACK([In] ref EVENT_TRACE_LOGFILE Logfile);

    [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Unicode)]
    public delegate uint HANDLER_FUNCTION_EX(
        [In] ServiceControlCode dwControl,
        [In] uint dwEventType,
        [In] UINT_PTR lpEventData,
        [In] UINT_PTR lpContext);

    [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Unicode)]
    public delegate JET_ERR JET_CALLBACK(
        [In] JET_SESID sesid,
        [In] JET_DBID dbid,
        [In] JET_TABLEID tableid,
        [In] JET_CBTYP cbtyp,
        [In, Out] UINT_PTR pvArg1,
        [In, Out] UINT_PTR pvArg2,
        [In] UINT_PTR pvContext,
        [In] UINT_PTR ulUnused);

    [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Unicode)]
    public delegate UINT_PTR JET_PFNREALLOC(
        [In] UINT_PTR pvContext,
        [In] UINT_PTR pv,
        [In] uint cb);

    /// <param name="pv">An optional pointer to a structure of type JET_SNPROG.</param>
    [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Unicode)]
    public delegate JET_ERR JET_PFNSTATUS(
        [In] JET_SESID sesid,
        [In] JET_SNP snp,
        [In] JET_SNT snt,
        [In] ref JET_SNPROG pv);

    [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Unicode)]
    public delegate bool MONITORENUMPROC(HMONITOR hMonitor, HDC hdcMonitor, ref RECT lprcMonitor, UINT_PTR dwData);

    [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Unicode)]
    public unsafe delegate void OVERLAPPED_COMPLETION_ROUTINE(
        [In] Win32ErrorCode dwErrorCode,
        [In] uint dwNumberOfBytesTransfered,
        [In] OVERLAPPED* lpOverlapped);

    [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Unicode)]
    public delegate void PTP_CLEANUP_GROUP_CANCEL_CALLBACK(
        UINT_PTR ObjectContext,
        UINT_PTR CleanupContext);

    [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Unicode)]
    public delegate void PTP_SIMPLE_CALLBACK(
        PTP_CALLBACK_INSTANCE Instance,
        UINT_PTR Context);

    /// <param name="Timer">This is actually PTP_TIMER but "safe handles cannot be marshaled from unmanaged to managed.</param>
    [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Unicode)]
    public delegate void PTP_TIMER_CALLBACK(
        PTP_CALLBACK_INSTANCE Instance,
        UINT_PTR Context,
        UINT_PTR Timer);

    /// <param name="Wait">This is actually PTP_WAIT but "safe handles cannot be marshaled from unmanaged to managed.</param>
    [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Unicode)]
    public delegate void PTP_WAIT_CALLBACK(
        PTP_CALLBACK_INSTANCE Instance,
        UINT_PTR Context,
        UINT_PTR Wait,
        uint WaitResult);

    /// <param name="Io">This is actually PTP_IO but "safe handles cannot be marshaled from unmanaged to managed.</param>
    [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Unicode)]
    public delegate void PTP_WIN32_IO_CALLBACK(
        PTP_CALLBACK_INSTANCE Instance,
        UINT_PTR Context,
        UINT_PTR Overlapped,
        uint IoResult,
        UINT_PTR NumberOfBytesTransferred,
        UINT_PTR Io);

    /// <param name="Work">This is actually PTP_WORK but "safe handles cannot be marshaled from unmanaged to managed.</param>
    [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Unicode)]
    public delegate void PTP_WORK_CALLBACK(
        PTP_CALLBACK_INSTANCE Instance,
        UINT_PTR Context,
        UINT_PTR Work);

    [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Unicode)]
    public delegate void SENDASYNCPROC(HWND hwnd, uint uMsg, UINT_PTR dwData, UINT_PTR lResult);

    [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Unicode)]
    public delegate void SERVICE_MAIN_FUNCTION(uint dwArgc, string[] lpszArgv);

    [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Unicode)]
    public delegate uint THREAD_START_ROUTINE(UINT_PTR lpParameter);

    [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Unicode)]
    public delegate void TIMERPROC(HWND hwnd, WindowMessageId uMsg, UINT_PTR idEvent, uint dwTime);

    [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Unicode)]
    public delegate uint WMIDPREQUEST(WMIDPREQUESTCODE RequestCode, UINT_PTR Context, ref uint Reserved, ref UINT_PTR Buffer);

    [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Unicode)]
    [return: MarshalAs(UnmanagedType.Bool)]
    public delegate bool WNDENUMPROC(HWND hwnd, UINT_PTR lParam);

    [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Unicode)]
    public delegate INT_PTR WNDPROC(HWND hwnd, WindowMessageId uMsg, UINT_PTR wParam, INT_PTR lParam);

    #region Delegates without an explicitly-typed Win32 counterpart

    [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Unicode)]
    public delegate INT_PTR CBTProc(CBTHookCode nCode, UINT_PTR wParam, ref CWPSTRUCT lParam);

    [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Unicode)]
    public delegate INT_PTR CallWndProc(HookCode nCode, UINT_PTR wParam, ref CWPSTRUCT lParam);

    [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Unicode)]
    public delegate INT_PTR CallWndRetProc(HookCode nCode, UINT_PTR wParam, ref CWPRETSTRUCT lParam);

    [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Unicode)]
    public delegate CopyProgressResult CopyProgressRoutine(
        long TotalFileSize,
        long TotalBytesTransferred,
        long StreamSize,
        long StreamBytesTransferred,
        uint dwStreamNumber,
        CopyProgressCallbackReason dwCallbackReason,
        HANDLE hSourceFile,
        HANDLE hDestinationFile,
        UINT_PTR lpData);

    [UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Unicode)]
    public delegate PDH_STATUS CounterPathCallBack(UINT_PTR dwArg);

    [UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Unicode)]
    public delegate INT_PTR GetMsgProc(HookCode nCode, UINT_PTR wParam, ref MSG lParam);

    [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Unicode)]
    public delegate INT_PTR JournalPlaybackProc(HookCode nCode, UINT_PTR wParam, ref EVENTMSG lParam);

    [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Unicode)]
    public delegate INT_PTR KeyboardProc(HookCode nCode, UINT_PTR wParam, INT_PTR lParam);

    /// <summary>
    /// 
    /// </summary>
    [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Unicode)]
    public delegate HRESULT TASKDIALOGCALLBACK(
        HWND hwnd,
        TaskDialogNotifications uNotification,
        UINT_PTR wParam,
        INT_PTR lParam,
        UINT_PTR lpRefData);

    [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Unicode)]
    public delegate void WINEVENTPROC(
        HWINEVENTHOOK hWinEventHook,
        WinEventCode uiEvent,
        HWND hwnd,
        int idObject,
        int idChild,
        uint dwEventThread,
        uint dwmsEventTime);

    [UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Unicode)]
    public delegate HRESULT EXCEPINFO_pfnDeferredFillIn(ref EXCEPINFO excepInfo);

    #endregion
}
